#!/usr/bin/env python
"""
    The Chat Handlers
    
    Copyright 2010 Netgamix LLC
    License: http://netgamix.com/information/terms/
    
"""
import string
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.ext.webapp import template
from google.appengine.api import channel
from django.utils import simplejson as json
from google.appengine.ext import db
from util.sessions import Session
import os,datetime,random,logging

class User(db.Model):
    nick=db.StringProperty(default="")
    channel_id=db.StringProperty(default="")
    
class Message(db.Model):
    text=db.StringProperty(default="")
    user=db.StringProperty(default="")
    

class Chat(db.Model):
  """All the data we store for a game"""
  userX = db.TextProperty()
  userO = db.TextProperty()
  userX_handle = db.StringProperty()
  userO_handle = db.StringProperty()
  userX_channel_id=db.StringProperty(default="")
  userO_channel_id=db.StringProperty(default="")
  chatX = db.TextProperty()
  chatO = db.TextProperty()
  userX_send_bool = db.BooleanProperty()
  chat_vcode = db.StringProperty()
  chat_closed = db.BooleanProperty()

class MainPage(webapp.RequestHandler):
  """The main UI page, renders the 'index.html' template."""
  def get(self):
    logging.info('main page')
    template_values = {'token': 'token'
                          }
    path = os.path.join(os.path.dirname(__file__), 'templates/index.html')
    self.response.out.write(template.render(path, template_values))


class WaitingPage(webapp.RequestHandler):
  """Waiting for another user.  Renders the 'waiting.html' template."""

  def get(self):
    """ Renders the waiting page.  Requires a channel to push a confirmation that the other user has joined. """
    chat_key = self.request.get('c')
    chat = None

    chat = Chat.get(chat_key)
    pubKey = chat.userX
    site_url = str(self.request.url)
    site_base = site_url.split('/')
    chat_vcode = ''.join(random.choice(string.letters) for i in xrange(7))
    chat_link = 'http://' + site_base[2] + '/join?c=' + chat_key + '&chat_vcode=' + chat_vcode

    #self.session = Session()

    channel_id=str(random.randint(1,10000))+str(datetime.datetime.now())

    chat_token = channel.create_channel(channel_id)
    chat.userX_channel_id = channel_id
    chat.chat_vcode = chat_vcode
    chat.put()

    if chat:
        #token = channel.create_channel(pubKey[:16] + chat_key[:16])
        template_values = {
                           'site_url': site_base[2],
                           'handle': chat.userX_handle,
                           'channel_id':channel_id,
                           'chat_key': chat_key,
                           'chat_link': chat_link,
                           'chat_token':chat_token
                          }
        path = os.path.join(os.path.dirname(__file__), 'templates/waiting.html')

        self.response.out.write(template.render(path, template_values))


class RegisterPage(webapp.RequestHandler):

  def post(self):
      logging.info("registering new chat")
      userkey = str(self.request.get('pubKey'))
      userhandle = str(self.request.get('handle'))

      chat = Chat(userX = userkey,
                  userX_handle = userhandle,
                  chat_closed = False
                  )
      thischat = chat.put()
      self.redirect('/waiting?c=' + str(thischat) )

class JoinPage(webapp.RequestHandler):
  """The join page, when the second user joins a chat.  renders the 'join.html' template."""
  def get(self):
    logging.info('join page')
    chatkey = str(self.request.get('c'))
    chat_vcode = str(self.request.get('chat_vcode'))
    template_values = {'token': 'token',
                       'chatkey': chatkey,
                       'chat_vcode': chat_vcode
                          }
    path = os.path.join(os.path.dirname(__file__), 'templates/join.html')
    self.response.out.write(template.render(path, template_values))


class JoinConfirm(webapp.RequestHandler):

  def get(self):
      logging.info("registering new chat")
      userkey = str(self.request.get('pubKey'))
      userhandle = str(self.request.get('handle'))
      chatkey = str(self.request.get('c'))
      chat_vcode = str(self.request.get('chat_vcode'))

      chat = Chat.get(chatkey)
      logging.info(chat_vcode)

      if chat.chat_vcode == chat_vcode:
        if chat.chat_closed == False:
          chat.userO = userkey
          chat.userO_handle = userhandle
          chat.put()

          logging.info('sending user joined message to channel')
          channel_msg = json.dumps({'success':True,"html":"joined"})
          channel.send_message(chat.userX_channel_id, channel_msg)

          self.redirect('/chatview?c=' + str(chat.key()) + '&u=o')
        else:
          self.response.out.write('this chat is closed')
      else:
        self.response.out.write('incorrect verification')

      
          
    
class MainHandler(webapp.RequestHandler):
    def get(self):
        #self.session = Session()
        error = self.session['error'] if 'error' in self.session else ""
        template_vars={'error':error}
        temp = os.path.join(os.path.dirname(__file__),'templates/main.html')
        outstr = template.render(temp, template_vars)
        self.response.out.write(outstr)
        
class ChatHandler(webapp.RequestHandler):
    def get(self):

        # Some session from http://gaeutilities.appspot.com/
        #self.session = Session()
        chat_key = self.request.get('c')
        chat = None
        chat = Chat.get(chat_key)

        channel_id=str(random.randint(1,10000))+str(chat.key())
        logging.info(channel_id)
        chat_token = channel.create_channel(channel_id)

        user_indicator = self.request.get('u')
        if user_indicator == 'x':
          logging.info('user X')
          handle = chat.userX_handle
          chat.userX_channel_id = channel_id
          userx_bool = True
          recipient_pubkey = chat.userO
          chat.put()
        elif user_indicator == 'o':
          logging.info('user O')
          handle = chat.userO_handle
          chat.userO_channel_id = channel_id
          userx_bool = False
          recipient_pubkey = chat.userX
          chat.put()
        else:
          ## unknown - probably the user refreshed the chat page.
          logging.info('ERROR')
          handle = "ERROR"
          recipient_pubkey = "xxx"


        # save the user
        #user = User(nick=nick,channel_id=channel_id)
        #user.put()
        # obtain all the messages
        #messages=Message.all().fetch(1000)
        # generate the template and answer back to the user
        template_vars={'nick':handle,
                       'recipient_pubkey': recipient_pubkey,
                       'userx_bool':userx_bool,
                       'channel_id':channel_id,
                       'user_indicator':user_indicator,
                       'chat_key':chat_key,
                       'chat_token':chat_token}
        temp = os.path.join(os.path.dirname(__file__),'templates/chat.html')
        outstr = template.render(temp, template_vars)
        self.response.out.write(outstr)
        
        
class NewMessageHandler(webapp.RequestHandler):
    
    def post(self):
        # Get the parameters
        #nick = self.request.get('nick')
        chat_key = self.request.get('chat_key')
        text = self.request.get('text')
        user_indicator = self.request.get('user_indicator')
        channel_id = self.request.get('channel_id')
        # Save the message sent by the user
        #user = User.all().filter('nick =',nick).get()
        #message=Message(user=user,text=text)
        #message.put()

        chat = None
        chat = Chat.get(chat_key)

        if user_indicator == 'x':
          logging.info('user_indicator: x')
          handle = chat.userX_handle
          chat.chatX = text
          chat.userX_send_bool = True
        else:
          logging.info('user_indicator: o')
          handle = chat.userO_handle
          chat.chatO = text
          chat.userX_send_bool = False

        
        chat.put()
        # Generate the template with the message
        messages=[chat]
        template_vars={'messages':messages}
        temp = os.path.join(os.path.dirname(__file__),'templates/messages.html')
        outstr = template.render(temp, template_vars)
        # Send the message to all the connected users
        #users = User.all().fetch(1000)

        # old way - this renders out a html formatted response
        #channel_msg = json.dumps({'success':True,"html":outstr})

        # new way - this sends the raw data
        
        if chat.userX_send_bool:
          channel_msg = json.dumps({'success': True, 'chat_data': chat.chatX})
          channel.send_message(chat.userO_channel_id, channel_msg)
        else:
          channel_msg = json.dumps({'success': True, 'chat_data': chat.chatO})
          channel.send_message(chat.userX_channel_id, channel_msg)
        
        # Reply to the user request
        self.response.out.write(outstr)
        
def main():
    application = webapp.WSGIApplication([
        ('/chat/', ChatHandler),
        ('/newMessage/',NewMessageHandler),
        ('/', MainPage),
        ('/waiting', WaitingPage),
        ('/register', RegisterPage),
        ('/join', JoinPage),
        ('/chatview', ChatHandler),
        ('/join_confirm', JoinConfirm)
        ],debug=True)
    util.run_wsgi_app(application)


if __name__ == '__main__':
    main()
